using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using RAG.Infrastructure.Data;
using RAG.Domain.Entities.App;
using System.Security.Claims;
using Microsoft.AspNetCore.Mvc;

namespace RAG.Api.Middleware
{
    public class PermissionAuthorizationMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<PermissionAuthorizationMiddleware> _logger;

        public PermissionAuthorizationMiddleware(RequestDelegate next, ILogger<PermissionAuthorizationMiddleware> logger)
        {
            _next = next;
            _logger = logger;
        }

        public async Task InvokeAsync(HttpContext context, RagDbContext dbContext)
        {
            // 检查是否需要权限验证
            if (ShouldCheckPermission(context))
            {
                var (hasPermission, errorMessage, requiredPermission) = await CheckUserPermissionAsync(context, dbContext);
                if (!hasPermission)
                {
                    context.Response.StatusCode = 403;
                    context.Response.ContentType = "application/json";
                    var errorResponse = new
                    {
                        code = 403,
                        message = errorMessage ?? "权限不足，无法访问此资源",
                        data = new
                        {
                            requiredPermission = requiredPermission,
                            path = context.Request.Path.Value,
                            method = context.Request.Method,
                            timestamp = DateTime.UtcNow
                        },
                        timestamp = DateTime.UtcNow
                    };
                    await context.Response.WriteAsJsonAsync(errorResponse);
                    return;
                }
            }

            await _next(context);
        }

        private bool ShouldCheckPermission(HttpContext context)
        {
            // 排除不需要权限验证的路径
            var excludedPaths = new[]
            {
                "/api/auth/",
                "/api/system/health",
                "/api/system/info",
                "/api/system/supported-file-types",
                "/api/system/test-document-processing",
                "/api/system/statistics",
                "/api/system/analytics",
                "/api/system/vectorization-status",
                "/api/users/avatar-file",
                // 仪表盘需要的全局问答统计，放行
                "/api/qa-management/statistics",
                // 会话修改等会话相关接口仅需认证，不做权限控制
                "/api/qa/sessions/",

            };

            var path = context.Request.Path.Value?.ToLower();
            return context.User?.Identity?.IsAuthenticated == true &&
                   path != null &&
                   path.StartsWith("/api/") &&
                   !excludedPaths.Any(excluded => path.StartsWith(excluded.ToLower()));
        }

        private async Task<(bool hasPermission, string? errorMessage, string? requiredPermission)> CheckUserPermissionAsync(HttpContext context, RagDbContext dbContext)
        {
            try
            {
                var userIdClaim = context.User.FindFirst("sub")?.Value
                    ?? context.User.FindFirst("user_id")?.Value
                    ?? context.User.FindFirst("uid")?.Value;

                if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var userId))
                {
                    _logger.LogWarning("无法获取用户ID进行权限验证");
                    return (false, "无法获取用户身份信息，请重新登录", null);
                }

                // 获取用户及其角色和权限
                var user = await dbContext.Users
                    .Include(u => u.Roles)
                    .ThenInclude(r => r.Permissions)
                    .FirstOrDefaultAsync(u => u.Id == userId);

                if (user == null)
                {
                    _logger.LogWarning("用户不存在: {UserId}", userId);
                    return (false, "用户不存在或已被删除", null);
                }

                // 检查用户状态
                if (!user.IsActive)
                {
                    _logger.LogWarning("用户账户已被禁用: {UserId}", userId);
                    return (false, "账户已被禁用，请联系管理员", null);
                }

                if (user.AccountStatus == 1)
                {
                    _logger.LogWarning("用户账户被锁定: {UserId}", userId);
                    return (false, "账户已被锁定，请稍后重试", null);
                }

                if (user.AccountStatus == 2)
                {
                    _logger.LogWarning("用户账户被永久禁用: {UserId}", userId);
                    return (false, "账户已被永久禁用，请联系管理员", null);
                }

                // 获取当前请求的权限代码
                var requiredPermission = GetRequiredPermission(context.Request);
                if (string.IsNullOrEmpty(requiredPermission))
                {
                    // 如果没有特定权限要求，则允许访问
                    return (true, null, null);
                }

                // 检查用户是否有所需权限
                var userPermissions = user.Roles
                    .SelectMany(r => r.Permissions)
                    .Select(p => p.PermissionCode)
                    .Distinct()
                    .ToList();

                var hasPermission = userPermissions.Any(p => p.Equals(requiredPermission, StringComparison.OrdinalIgnoreCase));

                if (!hasPermission)
                {
                    _logger.LogWarning("用户 {UserId} 缺少权限: {Permission}, 用户权限: {UserPermissions}", 
                        userId, requiredPermission, string.Join(", ", userPermissions));
                    
                    // 根据权限类型提供具体的错误信息
                    var errorMessage = GetPermissionErrorMessage(requiredPermission, userPermissions);
                    return (false, errorMessage, requiredPermission);
                }

                return (true, null, requiredPermission);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "权限验证过程中发生错误");
                return (false, "权限验证过程中发生错误，请稍后重试", null);
            }
        }

        private string? GetRequiredPermission(HttpRequest request)
        {
            var path = request.Path.Value?.ToLower();
            var method = request.Method.ToUpper();

            if (path == null) return null;

            // 定义API路径与权限代码的映射
            var permissionMap = new Dictionary<string, Dictionary<string, string>>
            {
                // 用户管理权限 - 区分超级管理员和普通用户
                ["/api/users"] = new Dictionary<string, string>
                {
                    ["GET"] = "user.view.all", // 超级管理员查看所有用户
                    ["POST"] = "user.create", // 超级管理员创建用户
                },
                ["/api/users/"] = new Dictionary<string, string>
                {
                    ["GET"] = "user.view.self", // 用户查看自己，超级管理员查看所有
                    ["PUT"] = "user.update.self", // 用户更新自己，超级管理员更新所有
                    ["DELETE"] = "user.delete", // 仅超级管理员删除
                    ["POST"] = "user.manage" // 仅超级管理员：启用/禁用等操作
                },

                // 角色管理权限 - 仅超级管理员
                ["/api/roles"] = new Dictionary<string, string>
                {
                    ["GET"] = "role.view",
                    ["POST"] = "role.create",
                    ["PUT"] = "role.update",
                    ["DELETE"] = "role.delete"
                },
                ["/api/roles/"] = new Dictionary<string, string>
                {
                    ["GET"] = "role.view",
                    ["PUT"] = "role.update",
                    ["DELETE"] = "role.delete",
                    ["POST"] = "role.manage" // 分配权限等操作
                },

                // 权限管理权限 - 仅超级管理员
                ["/api/permissions"] = new Dictionary<string, string>
                {
                    ["GET"] = "permission.view",
                    ["POST"] = "permission.create",
                    ["PUT"] = "permission.update",
                    ["DELETE"] = "permission.delete"
                },
                ["/api/permissions/"] = new Dictionary<string, string>
                {
                    ["GET"] = "permission.view",
                    ["PUT"] = "permission.update",
                    ["DELETE"] = "permission.delete"
                },

                // 知识库管理权限 - 用户管理自己的，超级管理员管理所有
                ["/api/knowledgebase"] = new Dictionary<string, string>
                {
                    ["GET"] = "knowledgebase.view.all", // 管理员查看所有知识库
                    ["POST"] = "knowledgebase.create", // 用户和超级管理员都可以创建
                },
                ["/api/knowledgebase/"] = new Dictionary<string, string>
                {
                    ["GET"] = "knowledgebase.view.all", // 管理员查看所有知识库
                    ["PUT"] = "knowledgebase.update.all", // 管理员更新所有知识库
                    ["DELETE"] = "knowledgebase.delete.all", // 管理员删除所有知识库
                    ["POST"] = "knowledgebase.manage" // 添加/移除文档等操作
                },

                // 文档管理权限 - 用户管理自己的，超级管理员管理所有
                ["/api/document"] = new Dictionary<string, string>
                {
                    ["GET"] = "document.view.all", // 管理员查看所有文档
                    ["POST"] = "document.create", // 用户和超级管理员都可以创建
                },
                ["/api/document/"] = new Dictionary<string, string>
                {
                    ["GET"] = "document.view.all", // 管理员查看所有文档
                    ["PUT"] = "document.update.all", // 管理员更新所有文档
                    ["DELETE"] = "document.delete.all", // 管理员删除所有文档
                },
                ["/api/document/upload"] = new Dictionary<string, string>
                {
                    ["POST"] = "document.create" // 用户和超级管理员都可以上传
                },
                ["/api/document/search"] = new Dictionary<string, string>
                {
                    ["POST"] = "document.view.all" // 管理员搜索所有文档
                },
                ["/api/document/batch-upload"] = new Dictionary<string, string>
                {
                    ["POST"] = "document.upload.batch" // 用户和超级管理员都可以批量上传
                },
                ["/api/document/"] = new Dictionary<string, string>
                {
                    ["PUT"] = "document.manage" // 更新文档权限等管理操作
                },

                // 问答管理权限 - 用户管理自己的，超级管理员管理所有
                ["/api/qa-management"] = new Dictionary<string, string>
                {
                    ["GET"] = "qa.view.all", // 用户查看自己的，超级管理员查看所有
                    ["DELETE"] = "qa.delete.all", // 用户删除自己的，超级管理员删除所有
                    ["POST"] = "qa.manage", // 用户管理自己的，超级管理员管理所有
                },
                ["/api/qa/generate-answer"] = new Dictionary<string, string>
                {
                    ["POST"] = "qa.generate" // 用户和超级管理员都可以生成答案
                },
                ["/api/qa/sessions"] = new Dictionary<string, string>
                {
                    ["GET"] = "qa.session.view.all", // 管理员查看所有会话
                    ["POST"] = "qa.session.create" // 用户和超级管理员都可以创建会话
                },
                ["/api/qa/sessions/"] = new Dictionary<string, string>
                {
                    ["GET"] = "qa.session.view.all", // 管理员查看所有会话
                    ["POST"] = "qa.session.message" // 用户和超级管理员都可以发送消息
                },
                ["/api/qa/retrieve-chunks"] = new Dictionary<string, string>
                {
                    ["GET"] = "qa.retrieve" // 用户和超级管理员都可以检索
                },
                ["/api/qa/user-conversations"] = new Dictionary<string, string>
                {
                    ["POST"] = "qa.conversation.view.all" // 管理员查看所有对话记录
                },

                // 向量管理权限 - 用户管理自己的，超级管理员管理所有
                ["/api/vector"] = new Dictionary<string, string>
                {
                    ["GET"] = "vector.view.all", // 管理员查看所有向量
                    ["POST"] = "vector.create", // 用户和超级管理员都可以创建
                    ["DELETE"] = "vector.delete.all" // 管理员删除所有向量
                },
                ["/api/vector/"] = new Dictionary<string, string>
                {
                    ["GET"] = "vector.view.all", // 管理员查看所有向量
                    ["DELETE"] = "vector.delete.all" // 管理员删除所有向量
                },
                ["/api/vector/generate-embedding"] = new Dictionary<string, string>
                {
                    ["POST"] = "vector.generate" // 用户和超级管理员都可以生成向量
                },
                ["/api/vector/generate-embeddings"] = new Dictionary<string, string>
                {
                    ["POST"] = "vector.generate.batch" // 用户和超级管理员都可以批量生成
                },
                ["/api/vector/calculate-similarity"] = new Dictionary<string, string>
                {
                    ["POST"] = "vector.similarity" // 用户和超级管理员都可以计算相似度
                },
                ["/api/vector/search-similar"] = new Dictionary<string, string>
                {
                    ["POST"] = "vector.search" // 用户和超级管理员都可以搜索
                }
            };

            // 查找匹配的权限
            foreach (var entry in permissionMap)
            {
                // 精确匹配或路径前缀匹配
                if (path == entry.Key || path.StartsWith(entry.Key))
                {
                    if (entry.Value.TryGetValue(method, out var permission))
                    {
                        return permission;
                    }
                }
            }

            return null; // 没有找到特定权限要求
        }

        /// <summary>
        /// 根据权限类型提供具体的错误信息
        /// </summary>
        private string GetPermissionErrorMessage(string requiredPermission, List<string> userPermissions)
        {
            // 权限分类映射
            var permissionCategories = new Dictionary<string, string>
            {
                // 用户管理权限
                ["user.view.all"] = "查看所有用户",
                ["user.create"] = "创建用户",
                ["user.update.all"] = "更新所有用户",
                ["user.delete"] = "删除用户",
                ["user.manage"] = "用户管理",
                ["user.view.self"] = "查看个人信息",
                ["user.update.self"] = "更新个人信息",

                // 角色管理权限
                ["role.view"] = "查看角色",
                ["role.create"] = "创建角色",
                ["role.update"] = "更新角色",
                ["role.delete"] = "删除角色",
                ["role.manage"] = "角色管理",

                // 权限管理权限
                ["permission.view"] = "查看权限",
                ["permission.create"] = "创建权限",
                ["permission.update"] = "更新权限",
                ["permission.delete"] = "删除权限",

                // 知识库管理权限
                ["knowledgebase.view.own"] = "查看知识库",
                ["knowledgebase.create"] = "创建知识库",
                ["knowledgebase.update.own"] = "更新知识库",
                ["knowledgebase.delete.own"] = "删除知识库",
                ["knowledgebase.manage"] = "知识库管理",

                // 文档管理权限
                ["document.view.own"] = "查看文档",
                ["document.create"] = "创建文档",
                ["document.update.own"] = "更新文档",
                ["document.delete.own"] = "删除文档",
                ["document.upload.batch"] = "批量上传文档",
                ["document.manage"] = "文档管理",

                // 问答管理权限
                ["qa.view.own"] = "查看问答",
                ["qa.view.all"] = "查看所有问答",
                ["qa.create"] = "创建问答",
                ["qa.delete.own"] = "删除自己的问答",
                ["qa.delete.all"] = "删除所有问答",
                ["qa.generate"] = "生成答案",
                ["qa.retrieve"] = "检索文档块",
                ["qa.session.view.own"] = "查看会话",
                ["qa.session.create"] = "创建会话",
                ["qa.session.message"] = "发送消息",
                ["qa.conversation.view.own"] = "查看对话记录",

                // 向量管理权限
                ["vector.view.own"] = "查看向量",
                ["vector.create"] = "创建向量",
                ["vector.delete.own"] = "删除向量",
                ["vector.generate"] = "生成向量",
                ["vector.generate.batch"] = "批量生成向量",
                ["vector.similarity"] = "计算相似度",
                ["vector.search"] = "向量搜索"
            };

            // 获取权限的中文名称
            var permissionName = permissionCategories.TryGetValue(requiredPermission, out var name) ? name : requiredPermission;

            // 检查用户是否有管理员权限
            var hasAdminPermissions = userPermissions.Any(p => p.StartsWith("user.") && p != "user.view.self" && p != "user.update.self");

            if (hasAdminPermissions)
            {
                return $"需要 {permissionName} 权限才能执行此操作。您当前拥有管理员权限，但缺少此特定权限。";
            }
            else
            {
                return $"需要 {permissionName} 权限才能执行此操作。您当前只有普通用户权限，无法执行此操作。";
            }
        }
    }
}
